﻿namespace MicroCloud.Extensions
{
    /// <summary>
    /// 服务集合接口辅助扩展方法类
    /// </summary>
    public static partial class IServiceCollectionExtensions
    {
        /// <summary>
        /// 构建微云平台系统服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <returns>微云平台系统构建器</returns>
        public static IMicroCloudBuilder AddMicroCloud(this IServiceCollection services)
        {
            Check.NotNull(services, nameof(services));

            //初始化所有程序集查找器
            services.GetOrAddSingleton(() => new StartupLogger());

            IMicroCloudBuilder builder = services.GetOrAddSingleton<IMicroCloudBuilder>(() => new MicroCloudBuilder(services));
            builder.AddCorePack();

            return builder;
        }

        /// <summary>
        /// 获取微云平台系统构建器
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <returns>微云平台系统构建器</returns>
        public static IMicroCloudBuilder GetMicroCloudBuilder(this IServiceCollection services)
        {
            Check.NotNull(services, nameof(services));

            IMicroCloudBuilder builder = services.GetOrAddSingleton<IMicroCloudBuilder>(() => new MicroCloudBuilder(services));
            return builder;
        }


        /// <summary>
        /// 获取<see cref="IHostEnvironment"/>环境信息
        /// </summary>
        /// <returns></returns>
        public static IHostEnvironment GetHostEnvironment(this IServiceCollection services)
        {
            return services.GetSingletonOrDefault<IHostEnvironment>();
        }

        /// <summary>
        /// 如果指定服务不存在，创建实例并添加。
        /// </summary>
        /// <typeparam name="TServiceType"></typeparam>
        /// <param name="services">服务集合</param>
        /// <param name="factory">服务工厂</param>
        /// <returns></returns>
        public static TServiceType GetOrAddSingleton<TServiceType>(this IServiceCollection services, Func<TServiceType> factory) where TServiceType : class
        {
            TServiceType item = services.GetSingletonOrDefault<TServiceType>();
            if (item == null)
            {
                item = factory();
                services.AddSingleton(item);
                services.ServiceLogDebug(typeof(TServiceType), item.GetType(), typeof(IServiceCollectionExtensions).Name);
            }
            return item;
        }

        /// <summary>
        /// 加载事件处理器
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddEventHandler<T>(this IServiceCollection services) where T : class, IEventHandler
        {
            return services.AddTransient<T>();
        }
        





        #region "添加服务调试级别日志"
        /// <summary>
        /// 添加服务调试级别日志
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="oldDescriptors">服务描述器</param>
        /// <param name="logType">日志类型</param>
        /// <returns></returns>
        public static IServiceCollection ServiceLogDebug(this IServiceCollection services, ServiceDescriptor[] oldDescriptors, Type logType)
        {
            var list = services.Except(oldDescriptors);
            foreach (ServiceDescriptor desc in list)
            {
                if (desc.ImplementationType != null)
                {
                    services.ServiceLogDebug(desc.ServiceType, desc.ImplementationType, logType, desc.Lifetime);
                    continue;
                }

                if (desc.ImplementationInstance != null)
                {
                    services.ServiceLogDebug(desc.ServiceType, desc.ImplementationInstance.GetType(), logType, desc.Lifetime);
                }
            }

            return services;
        }
        #endregion
        #region "添加服务调试级别日志"
        /// <summary>
        /// 添加服务调试级别日志
        /// </summary>
        /// <typeparam name="TServiceType">服务类型</typeparam>
        /// <typeparam name="TImplementType">服务实例类型</typeparam>
        /// <param name="services">服务集合</param>
        /// <param name="logType">日志类型</param>
        /// <param name="lifetime">服务生命周期</param>
        /// <returns></returns>
        public static IServiceCollection ServiceLogDebug<TServiceType, TImplementType>(this IServiceCollection services, Type logType, ServiceLifetime lifetime = ServiceLifetime.Singleton)
        {
            Type serviceType = typeof(TServiceType), implementType = typeof(TImplementType);
            return services.ServiceLogDebug(serviceType, implementType, logType, lifetime);
        }

        #endregion   
    }
}